//
// 通用定时器框架
// Created by kenny on 25-11-6.
//
#include <stdlib.h>
#include <stdio.h>
#include "comm_timer.h"
#ifdef _WIN32
#include <windows.h>
#define THREAD_RETURN_TYPE DWORD WINAPI
#define THREAD_RETURN return 0
#else
#include <pthread.h>
#define THREAD_RETURN_TYPE void*
#define THREAD_RETURN return NULL
#endif

// 统一的线程函数
static THREAD_RETURN_TYPE timer_thread_func(void* param)
{
    comm_timer_t* timer = (comm_timer_t*)param;
    const platform_timer_ops_t* ops = get_platform_timer_ops();

    if (!ops->start(timer->platform_timer)) {
        THREAD_RETURN;
    }

    while (timer->state == TIMER_RUNNING) {
        // 等待定时器超时或停止信号
        ops->wait(timer->platform_timer);

        // 检查是否停止
        if (timer->state != TIMER_RUNNING) {
            break;
        }

        // 执行上报函数
        if (timer->config.user_func) {
            timer->config.user_func(timer->config.user_data);
        }
    }

    THREAD_RETURN;
}

comm_timer_t* comm_timer_create(const timer_config_t* config)
{
    if (!config || !config->user_func || config->interval_sec == 0) {
        return NULL;
    }

    comm_timer_t* timer = malloc(sizeof(comm_timer_t));
    if (!timer) return NULL;

    timer->config = *config;
    timer->state = TIMER_STOPPED;
    timer->thread_handle = NULL;

    const platform_timer_ops_t* ops = get_platform_timer_ops();
    timer->platform_timer = ops->create(config->interval_sec);
    if (!timer->platform_timer) {
        free(timer);
        return NULL;
    }

    return timer;
}

bool comm_timer_start(comm_timer_t* timer)
{
    if (!timer || timer->state != TIMER_STOPPED || !timer->config.enabled) {
        return false;
    }

    timer->state = TIMER_RUNNING;

#ifdef _WIN32
    timer->thread_handle = CreateThread(NULL, 0, timer_thread_func, timer, 0, NULL);
    if (!timer->thread_handle) {
        timer->state = TIMER_STOPPED;
        return false;
    }
#else
    if (pthread_create((pthread_t*)&timer->thread_handle, NULL,
                      (void* (*)(void*))timer_thread_func, timer) != 0) {
        timer->state = TIMER_STOPPED;
        return false;
    }
#endif

    return true;
}

bool comm_timer_stop(comm_timer_t* timer)
{
    if (!timer || timer->state != TIMER_RUNNING) {
        return false;
    }

    timer->state = TIMER_STOPPED;

    const platform_timer_ops_t* ops = get_platform_timer_ops();
    ops->stop(timer->platform_timer);

#ifdef _WIN32
    if (timer->thread_handle) {
        WaitForSingleObject(timer->thread_handle, INFINITE);
        CloseHandle(timer->thread_handle);
        timer->thread_handle = NULL;
    }
#else
    if (timer->thread_handle) {
        pthread_join((pthread_t)timer->thread_handle, NULL);
        timer->thread_handle = NULL;
    }
#endif

    return true;
}

bool comm_timer_destroy(comm_timer_t* timer)
{
    if (!timer) return false;

    if (timer->state == TIMER_RUNNING) {
        comm_timer_stop(timer);
    }

    const platform_timer_ops_t* ops = get_platform_timer_ops();
    if (timer->platform_timer) {
        ops->destroy(timer->platform_timer);
    }

    free(timer);
    timer = NULL;
    return true;
}